#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2025/10/4 9:59
# @Author  : summer
# @Email   : 610658552@qq.com
# @File    : ser_account.py
# @Software: PyCharm
# @Desc    :

from rest_framework import serializers
from common.models import Account  # 关联校区模型


class AccountSerializer(serializers.ModelSerializer):
    """
    Account序列化器：
    1. 密码加密存储（不返回原始密码）
    2. 用户名/手机号唯一性校验
    3. 手机号格式校验
    4. 关联校区名称显示（只读）
    """
    # 密码：只在创建/更新时接收，返回时隐藏（避免密码泄露）
    password = serializers.CharField(write_only=True, required=False, allow_blank=True)

    class Meta:
        model = Account
        # 明确指定返回字段（排除敏感字段如token、openid，及内部状态字段is_delete/pt_flag）
        fields = [
            "id", "username", "mobile", "status", "is_admin", "last_login_time",
            "sort_num", "is_active", "create_time", "update_time",
            "password"  # 仅用于写入，返回时自动隐藏
        ]
        # 只读字段：创建时间、更新时间、最后登录时间等不可手动修改
        read_only_fields = ["create_time", "update_time", "last_login_time", "token", "openid"]

    def validate_username(self, value):
        """
        用户名校验规则：
        1. 不能为空且去空格后不为空
        2. 新增时：在有效账号中唯一
        3. 更新时：排除当前账号后唯一
        """
        # 处理空值和空格
        if not value or not value.strip():
            raise serializers.ValidationError("用户名不能为空！")
        normalized_name = value.strip()

        # 只校验「未删除+非压测」的有效账号
        queryset = Account.objects.filter(is_delete=0, pt_flag=0)

        # 区分新增/更新场景
        if self.instance is None:
            # 新增：检查用户名是否已存在
            if queryset.filter(username=normalized_name).exists():
                raise serializers.ValidationError(f"用户名「{normalized_name}」已存在，请更换！")
        else:
            # 更新：排除当前账号后检查唯一性
            if queryset.exclude(id=self.instance.id).filter(username=normalized_name).exists():
                raise serializers.ValidationError(f"用户名「{normalized_name}」已被其他账号使用，请更换！")
        return normalized_name

    def validate_mobile(self, value):
        """
        手机号校验规则：
        1. 可为空（允许无手机号账号）
        2. 非空时需为11位数字（符合国内手机号格式）
        3. 有效账号中手机号唯一
        """
        # 空值直接返回（允许无手机号）
        if not value:
            return ""

        # 去空格后校验格式
        normalized_mobile = value.strip()
        if not (normalized_mobile.isdigit() and len(normalized_mobile) == 11):
            raise serializers.ValidationError("手机号格式不正确，请输入11位数字！")

        # 校验手机号唯一性（仅针对有效账号）
        queryset = Account.objects.filter(is_delete=0, pt_flag=0)
        if self.instance is None:
            # 新增：手机号已存在
            if queryset.filter(mobile=normalized_mobile).exists():
                raise serializers.ValidationError(f"手机号「{normalized_mobile}」已绑定其他账号！")
        else:
            # 更新：排除当前账号后手机号已存在
            if queryset.exclude(id=self.instance.id).filter(mobile=normalized_mobile).exists():
                raise serializers.ValidationError(f"手机号「{normalized_mobile}」已绑定其他账号，请更换！")
        return normalized_mobile

    def create(self, validated_data):
        """重写创建逻辑：密码加密存储（若传了密码）"""
        # 提取密码（validated_data中已包含password字段，需手动处理）
        password = validated_data.pop('password', None)
        # 创建账号实例
        account = Account.objects.create(**validated_data)
        # 若传了密码，调用模型的set_password方法加密
        if password:
            account.set_password(password)
            account.save()
        return account

    def update(self, instance, validated_data):
        """重写更新逻辑：密码加密更新（若传了密码）"""
        # 提取密码（若前端传了password则更新，否则不修改）
        password = validated_data.pop('password', None)
        # 先更新其他字段
        for attr, value in validated_data.items():
            setattr(instance, attr, value)
        # 若传了密码，加密后更新
        if password:
            instance.set_password(password)
        instance.save()
        return instance
